pub mod resp;
pub mod parser;
pub mod encoder;

use bytes::Bytes;
use thiserror::Error;

pub use resp::*;
pub use parser::*;
pub use encoder::*;

/// Redis protocol errors
#[derive(Error, Debug)]
pub enum ProtocolError {
    #[error("Invalid protocol format: {0}")]
    InvalidFormat(String),

    #[error("Incomplete data")]
    IncompleteData,

    #[error("Invalid command: {0}")]
    InvalidCommand(String),

    #[error("Wrong number of arguments for command: {0}")]
    WrongArgumentCount(String),

    #[error("Invalid argument type")]
    InvalidArgumentType,

    #[error("IO error: {0}")]
    IoError(#[from] std::io::Error),
}

pub type ProtocolResult<T> = Result<T, ProtocolError>;

/// Redis command representation
#[derive(Debug, Clone, PartialEq)]
pub struct RedisCommand {
    pub name: String,
    pub args: Vec<String>,
}

impl RedisCommand {
    pub fn new(name: String, args: Vec<String>) -> Self {
        Self { name, args }
    }

    pub fn arg_count(&self) -> usize {
        self.args.len()
    }

    pub fn get_arg(&self, index: usize) -> Option<&String> {
        self.args.get(index)
    }
}